package com.cgx.tablet.beeper.database;

import android.content.Context;
import android.support.annotation.NonNull;

import java.util.List;

import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmObject;
import io.realm.Sort;

/**
 * Realm数据库帮助类
 * https://realm.io/docs/java/latest
 * http://www.jianshu.com/p/28912c2f31db
 * Created by admin on 2016/12/16.
 */

public class DatabaseHelper {

    public static void init(Context context) {
        Realm.init(context);
        RealmConfiguration configuration = new RealmConfiguration.Builder()
                .name("tablet_beeper.realm")
                .deleteRealmIfMigrationNeeded()
                .build();
        Realm.setDefaultConfiguration(configuration);
    }

    /**
     * 增
     *
     * @param realmBean 继承RealmObject的JavaBean
     */
    public static <T extends RealmObject> void addToDB(final T realmBean, final DBOperationSimpleListener listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                realm.copyToRealm(realmBean);
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                listener.onOperateDBSuccess();
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onOperateDBFail(error.getMessage());
            }
        });
    }

    /**
     * 一次
     */
    public static <T extends RealmObject> void addMultiToDB(final List<T> realmBeanList, final DBOperationSimpleListener listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                for (T realmBean : realmBeanList) {
                    realm.copyToRealm(realmBean);
                }
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                listener.onOperateDBSuccess();
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onOperateDBFail(error.getMessage());
            }
        });
    }

    /**
     * 删除第一条数据
     *
     * @param clazz    继承RealmObject的class
     * @param listener 回调
     */
    public static <T extends RealmObject> void deleteFirst(final Class<T> clazz, final DBOperationSimpleListener listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                T realmObject = realm.where(clazz).findFirst();
                if (realmObject != null) {
                    realmObject.deleteFromRealm();
                }
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                listener.onOperateDBSuccess();
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onOperateDBFail(error.getMessage());
            }
        });
    }

    /**
     * 通过id,type删除，所以RealmObject必须要有id,type字段
     *
     * @param clazz 继承RealmObject的class
     * @param ids   多个id
     * @param type  类型
     */
    public static <T extends RealmObject> void deleteById(final Class<T> clazz, final long[] ids, final int type, final DBQueryListener<T> listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                for (long id : ids) {
                    T realmObject = realm.where(clazz).equalTo("id", id).findFirst();
                    if (realmObject != null) {
                        realmObject.deleteFromRealm();
                    }
                }
                List<T> resultList = realm.copyFromRealm(realm.where(clazz)
                        .equalTo("type", type).sort("id", Sort.ASCENDING).findAll());
                listener.onQueryDBSuccess(resultList);
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onQueryDBFail(error.getMessage());
            }
        });
    }

    public static <T extends RealmObject> void deleteById(final Class<T> clazz, final long id, final DBQueryListener<T> listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                T realmObject = realm.where(clazz).equalTo("id", id).findFirst();
                if (realmObject != null) {
                    realmObject.deleteFromRealm();
                }
                List<T> resultList = realm.copyFromRealm(realm.where(clazz).sort("id", Sort.ASCENDING).findAll());
                listener.onQueryDBSuccess(resultList);
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onQueryDBFail(error.getMessage());
            }
        });
    }

    /**
     * 删除表中所有数据
     *
     * @param clazz 继承RealmObject的class
     */
    public static <T extends RealmObject> void deleteAll(final Class<T> clazz, final DBOperationSimpleListener listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                realm.delete(clazz);
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                listener.onOperateDBSuccess();
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onOperateDBFail(error.getMessage());
            }
        });
    }

    /**
     * 查表的第一条数据
     *
     * @param clazz    继承RealmObject的class
     * @param listener 回调
     */
    public static <T extends RealmObject> void queryFirst(final Class<T> clazz, final DBQueryFirstListener<T> listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                T realmObject = realm.where(clazz).findFirst();
                if (realmObject != null) {
                    listener.onQueryDBSuccess(realm.copyFromRealm(realmObject));
                } else {
                    listener.onQueryDBFail("not found in database");
                }
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onQueryDBFail(error.getMessage());
            }
        });
    }

    /**
     * 查询所有数据，这个方法只针对灯或者含有type字段的RealmObject
     *
     * @param clazz    继承RealmObject的class
     * @param type     灯的类型
     * @param listener 能够返回List
     */
    public static <T extends RealmObject> void queryByType(final Class<T> clazz, final int type, final DBQueryListener<T> listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                List<T> resultList = realm.copyFromRealm(realm.where(clazz)
                        .equalTo("type", type).sort("id", Sort.ASCENDING).findAll());
                listener.onQueryDBSuccess(resultList);
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onQueryDBFail(error.getMessage());
            }
        });
    }

    /**
     * 查询所有数据，RealmObject
     *
     * @param clazz    继承RealmObject的class
     * @param listener 能够返回List
     */
    public static <T extends RealmObject> void queryAll(final Class<T> clazz, final DBQueryListener<T> listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                List<T> resultList = realm.copyFromRealm(realm.where(clazz).sort("id", Sort.ASCENDING).findAll());
                listener.onQueryDBSuccess(resultList);
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onQueryDBFail(error.getMessage());
            }
        });
    }

    /**
     * 排序查询所有数据，RealmObject
     *
     * @param clazz     继承RealmObject的class
     * @param fieldName 参数名字
     * @param sortOrder 排序方式 Sort.ASCENDING（升序） Sort.DESCENDING（降序）
     * @param listener  能够返回List
     */
    public static <T extends RealmObject> void queryAll(final Class<T> clazz, final String fieldName, final Sort sortOrder, final DBQueryListener<T> listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                List<T> resultList = realm.copyFromRealm(realm.where(clazz).sort(fieldName, sortOrder).findAll());
                listener.onQueryDBSuccess(resultList);
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onQueryDBFail(error.getMessage());
            }
        });
    }

    /**
     * 更新
     *
     * @param realmBean 继承RealmObject的JavaBean
     */
    public static <T extends RealmObject> void update(final T realmBean, final DBOperationSimpleListener listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                realm.copyToRealmOrUpdate(realmBean);
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                listener.onOperateDBSuccess();
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onOperateDBFail(error.getMessage());
            }
        });
    }

    /**
     * @param realmBeanList 继承RealmObject的JavaBean的列表
     */
    public static <T extends RealmObject> void multiUpdate(final List<T> realmBeanList, final DBOperationSimpleListener listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                for (T realmBean : realmBeanList) {
                    realm.copyToRealmOrUpdate(realmBean);
                }
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                listener.onOperateDBSuccess();
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onOperateDBFail(error.getMessage());
            }
        });
    }

    public static <T extends RealmObject> void getAmountLessThan(final Class<T> clazz, final String fieldName, final int value, final DBDataAmountListener listener) {
        Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                long amount = realm.where(clazz).lessThan(fieldName, value).count();
                listener.onGetAmountSuccess(amount);
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(@NonNull Throwable error) {
                listener.onGetAmountFail(error.getMessage());
            }
        });
    }

}
